﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Runtime.InteropServices;
using System.IO;
using System.Drawing;
using BaseHelper.Encrypt;
using RTSDK;

namespace DeviceSDK.Park.Vz
{
    class VzSDK
    {

        //public static event DeviceSDK.Park.ParkHandler.OnCarArriveGateHandler OnCarArriveGateEvent;

        private static VzClientSDK.VZDEV_SERIAL_RECV_DATA_CALLBACK _serialRecv = null;
        private static SortedList<string, VzClientSDK.VZLPRC_PLATE_INFO_CALLBACK> _slCallBack = new SortedList<string, VzClientSDK.VZLPRC_PLATE_INFO_CALLBACK>();
        private static VzClientSDK.VZLPRC_PLATE_INFO_CALLBACK OnQueryPlateInfo = null;


        private static object locker = new object();
        //private static string _caridcolor = "未蓝黄白黑绿";
        private static string _carcolor = "深浅白灰黄粉红绿蓝棕";
        private static string[] _caridtypeid = new string[] { "未知", "蓝牌小汽车", "黑牌小汽车", "单排黄牌", "双排黄牌", "警车", "武警", "个性车牌", "单排军车", "双排军车", "使馆车", "香港通行车", "农用车", "教练车", "澳门通行车", "双层武警车", "武警总队车", "双层武警总队车", "民航车牌", "新能源" };

        private static SortedList<string, int> _slIpToHandle = new SortedList<string, int>();
        private static SortedList<int, string> _slHandleToIp = new SortedList<int, string>();
        private static SortedList<string, int> _slIpToPicHandle = new SortedList<string, int>();
        private static SortedList<string, int> _slSerialHandle = new SortedList<string, int>();
        private static bool _isInit = false;
        private static string _tempFolder = "";
        private static int _repeatTimeout = 5;

        private static SortedList<string,DateTime> _slLastCar =new SortedList<string, DateTime>();
        public static string GetError(int err)
        {
            switch (err)
            {
                case -1: return "操作失败！";
                case -2: return "登录设备时发生错误！";
                case -3: return "尚未建立设备连接！";
                case -4: return "无法获取预览画面！";
                case -5: return "操作道闸失败！";
                case -6: return "串口操作失败！";
            
            }

            return "未知错误！";
        }

        #region 基本

        private static int GetConnect(string ip)
        {
            if (_slIpToHandle.ContainsKey(ip))
                return _slIpToHandle[ip];
            else
                return 0;
        }

        public static bool Init(string tempFolder)
        {
            if (_isInit)
                return false;
            
            VzClientSDK.VzLPRClient_Setup();
               
            
            _tempFolder = tempFolder;
            if (!Directory.Exists(tempFolder))
            {
                Directory.CreateDirectory(tempFolder);
            } 
            _isInit = true;
            return true;
        }

        public static void Close(string ip)
        {
            try
            {
                StopPreview(ip);
            }
            catch (Exception ex)
            {
                Console.WriteLine("VZSDK.cs->Close()" + ip);
            }

            try
            {
                if(_slIpToPicHandle.ContainsKey(ip))
                    _slIpToHandle.Remove(ip);

                if(_slCallBack.ContainsKey(ip))
                    _slCallBack.Remove(ip);

                if(_slIpToPicHandle.ContainsKey(ip))
                    _slIpToPicHandle.Remove(ip);

                if(_slSerialHandle.ContainsKey(ip))
                    _slSerialHandle.Remove(ip);

            }
            catch (Exception ex)
            {
                Console.WriteLine("VZSDK.cs->Close()" + ip);
            }

            try
            {
                VzClientSDK.VzLPRClient_CloseByIP(ip);
            }
            catch 
            { }
        }

        private static int Connect(string ip, string user, string pass, int port)
        {
            if (_slIpToHandle.ContainsKey(ip))
            { 

                byte stat = 0;
                VzClientSDK.VzLPRClient_IsConnected(_slIpToHandle[ip], ref stat);

                if (stat == 1)
                 return _slIpToHandle[ip];
            }
            int ret = VzClientSDK.VzLPRClient_Open(ip.Trim(), (ushort)port, user, pass);
            if (ret == 0)
                return 0;

            if (_slIpToHandle.ContainsKey(ip))
                _slIpToHandle[ip] = ret;
            else
                _slIpToHandle.Add(ip, ret);

            if (_slHandleToIp.ContainsKey(ret))
                _slHandleToIp[ret] = ip;
            else
                _slHandleToIp.Add(ret, ip);


            return ret;
        }

        public static int SetListen(string caption, string ip, string user, string pass, int port)
        {
            int ret = Connect(ip, user, pass, port);
            if (ret == 0)
                return -2;


            VzClientSDK.VZLPRC_PLATE_INFO_CALLBACK callBack = new VzClientSDK.VZLPRC_PLATE_INFO_CALLBACK(OnPlateResult);
            VzClientSDK.VzLPRClient_SetPlateInfoCallBack(ret, callBack, IntPtr.Zero, 1);

            if (!_slCallBack.ContainsKey(ip))
                _slCallBack.Add(ip, callBack);
            else
                _slCallBack[ip] = callBack;

            return 1;
        }

        public static int PlayPreview(string ip, IntPtr pichandle)
        {
            if (!_slIpToHandle.ContainsKey(ip))
                return -3;

            
            int ret = VzClientSDK.VzLPRClient_StartRealPlay(_slIpToHandle[ip], pichandle);
            if(ret==0)
               return -4;

            if (_slIpToPicHandle.ContainsKey(ip))
                _slIpToPicHandle[ip] = ret;
            else
                _slIpToPicHandle[ip] = ret;

            return 1;
        }

        public static int StopPreview(string ip,int pichandle=0)
        {
            if (pichandle == 0)
            {
                if (_slIpToPicHandle.ContainsKey(ip))
                    pichandle = _slIpToPicHandle[ip];
                else
                    return -1;
            }
           
            return VzClientSDK.VzLPRClient_StopRealPlay(pichandle);//);
        }

        public static int SetGateStatus(string ip, bool isOpen)
        {
            int ret = GetConnect(ip);
            if (ret == 0)
                return -2;

            if (!_slIpToHandle.ContainsKey(ip))
                return -3;
            int handle = _slIpToHandle[ip];
            return VzClientSDK.VzLPRClient_SetIOOutputAuto(handle, isOpen ? 0 : 1, 500) == 0 ? 1 : -4;
        }

        public static int SetManualSnapshot(string ip)
        {
            int ret = GetConnect(ip);
            if (ret == 0)
                return -2;

            int handle = _slIpToHandle[ip];

            return VzClientSDK.VzLPRClient_ForceTrigger(handle);
        }

        public static Image GetSnapShootToJpeg(string ip)
        {
            int ret = GetConnect(ip);
            if (ret == 0)
                return null;

            if (!_slIpToPicHandle.ContainsKey(ip))
                return null;

            int handle = _slIpToPicHandle[ip];

            string filepath=_tempFolder + DateTime.Now.Ticks + ".jpg";

            ret= VzClientSDK.VzLPRClient_GetSnapShootToJpeg2(handle,filepath,50);
            if (ret == 0)
                return Image.FromFile(filepath);
            else
                return null;
        }

        public static int SetOSD(string ip, string osd)
        {
            int ret = GetConnect(ip);
            if (ret == 0)
                return -2;

            int handle = _slIpToHandle[ip];


            while (Encoding.Default.GetBytes(osd).Length > 16)
            {
                osd = osd.Substring(0, osd.Length - 1);
            }
            try
            {
                VzClientSDK.VZ_LPRC_OSD_Param osdParam = new VzClientSDK.VZ_LPRC_OSD_Param();

                int m_hwType = 0;
                ret = VzClientSDK.VzLPRClient_GetHwBoardType(handle, ref m_hwType);

                int size = Marshal.SizeOf(osdParam);
                IntPtr intptr = Marshal.AllocHGlobal(size);
                Marshal.StructureToPtr(osdParam, intptr, true);
                VzClientSDK.VzLPRClient_GetOsdParam(handle, intptr);
                osdParam = (VzClientSDK.VZ_LPRC_OSD_Param)Marshal.PtrToStructure(intptr, typeof(VzClientSDK.VZ_LPRC_OSD_Param));

                osdParam.dstampenable = (byte)1;
                osdParam.tstampenable = (byte)1;
                osdParam.nTextEnable = (byte)1;

                osdParam.datePosX = 0;
                osdParam.datePosY = 0;
                osdParam.timePosX = 127;
                osdParam.timePosY = 0;
                osdParam.nTextPositionX = 232;// (232 * width + (1 << 13)) >> 14; ;
                osdParam.nTextPositionY = 0;

                osdParam.overlaytext = osd;
                osdParam.dateFormat = 0;
                osdParam.timeFormat = 1;

                size = Marshal.SizeOf(osdParam);
                intptr = Marshal.AllocHGlobal(size);
                Marshal.StructureToPtr(osdParam, intptr, true);
                ret = VzClientSDK.VzLPRClient_SetOsdParam(handle, intptr);
                Marshal.FreeHGlobal(intptr);
            }
            catch (Exception ex)
            { 
            
            }
            return ret;
        }

        public static int SetTime(string ip,DateTime dt)
        {
            int ret = GetConnect(ip);
            if (ret == 0)
                return -2;

            int handle = _slIpToHandle[ip];

            try
            {
                //设置LED时间
                SetLedTime(ip, dt);

                VzClientSDK.VZ_DATE_TIME_INFO TimeInfo = new VzClientSDK.VZ_DATE_TIME_INFO();

                TimeInfo.uYear = (uint)dt.Year;
                TimeInfo.uMonth = (uint)dt.Month;
                TimeInfo.uMDay = (uint)dt.Day;
                TimeInfo.uHour = (uint)dt.Hour;
                TimeInfo.uMin = (uint)dt.Minute;
                TimeInfo.uSec = (uint)dt.Second;

                int timesize = Marshal.SizeOf(TimeInfo);
                IntPtr timeptr = Marshal.AllocHGlobal(timesize);
                Marshal.StructureToPtr(TimeInfo, timeptr, true);
                ret = VzClientSDK.VzLPRClient_SetDateTime(handle, timeptr);
            }
            catch (Exception ex)
            { 
            
            
            }

            return ret;
        }

        public static int GetHistory(string ip,string carID,string startTime,string endTime)
        {
          if (!_slIpToHandle.ContainsKey(ip))
                return -3;

            int handle=_slIpToHandle[ip];


            OnQueryPlateInfo = new VzClientSDK.VZLPRC_PLATE_INFO_CALLBACK(OnPlateResult);
            VzClientSDK.VzLPRClient_SetQueryPlateCallBack(handle, OnQueryPlateInfo, IntPtr.Zero);


            int count = VzClientSDK.VzLPRClient_QueryCountByTimeAndPlate(handle, startTime, endTime, carID);


            VzClientSDK.VzLPRClient_QueryPageRecordByTimeAndPlate(handle, startTime, endTime, carID, 0,count);


            return count;
        }


        //private static int gOnQueryPlateInfo(int handle, IntPtr pUserData,
        //                                    IntPtr pResult, uint uNumPlates,
        //                                    VzClientSDK.VZ_LPRC_RESULT_TYPE eResultType,
        //                                    IntPtr pImgFull,
        //                                    IntPtr pImgPlateClip)
        //{
        //    Console.WriteLine(eResultType);
        //    if (pUserData != null && pResult != null)
        //    {
        //        VzClientSDK.TH_PlateResult result = (VzClientSDK.TH_PlateResult)Marshal.PtrToStructure(pResult, typeof(VzClientSDK.TH_PlateResult));
        //        if (pResult != null)
        //        {
        //            string strPlateID = result.uId.ToString();
        //            string license = new string(result.license);
        //            string time = result.struBDTime.bdt_year + "-" + result.struBDTime.bdt_mon.ToString().PadLeft(2, '0') +
        //                "-" + result.struBDTime.bdt_mday.ToString().PadLeft(2, '0') + " " + result.struBDTime.bdt_hour.ToString().PadLeft(2, '0') +
        //                ":" + result.struBDTime.bdt_min.ToString().PadLeft(2, '0') + ":" +
        //                result.struBDTime.bdt_sec.ToString().PadLeft(2, '0');


        //            Console.WriteLine(license);
        //        }
        //    }
        //    return 0;
        //}

        #endregion

        private static int OnPlateResult(int handle, IntPtr pUserData, IntPtr pResult, uint uNumPlates,VzClientSDK.VZ_LPRC_RESULT_TYPE eResultType,IntPtr imgHandler,IntPtr imgCarIDHandle)
        {
            try
            {
                if (eResultType != VzClientSDK.VZ_LPRC_RESULT_TYPE.VZ_LPRC_RESULT_REALTIME)
                {
                    CarInfo car = new CarInfo();

                    VzClientSDK.TH_PlateResult result = (VzClientSDK.TH_PlateResult)Marshal.PtrToStructure(pResult, typeof(VzClientSDK.TH_PlateResult));
                    car.CarID = new string(result.license).Trim().Replace("_","").Replace("\0","");
                    if (car.CarID.Length > 0)
                    {
                        if (car.CarID[0] > 100)
                        {
                            car.CarAreaID = car.CarID[0].ToString();
                            car.CarIDShort = car.CarID.Substring(1, car.CarID.Length - 1);
                        }
                        else
                        {
                            car.CarAreaID = "";
                            car.CarIDShort = car.CarID;
                        }
                    }
                    else
                    {
                        car.CarAreaID = "无";
                        car.CarIDShort = "";
                    }

                    lock (locker)
                    {
                        try
                        {
                            if (_slLastCar.ContainsKey(car.CarID))
                            {
                                if (_slLastCar[car.CarID].AddSeconds(_repeatTimeout) > DateTime.Now)
                                    return 0;

                            }
                            _slLastCar[car.CarID] = DateTime.Now;
                            string[] carids = _slLastCar.Keys.ToArray<string>();
                            foreach (string carid in carids)
                            {
                                if (_slLastCar[carid].AddSeconds(_repeatTimeout) < DateTime.Now)
                                    _slLastCar.Remove(carid);
                            }
                        }
                        catch { }
                    }
                    
                    car.CarIDColor = new string(result.color).Replace("\0","").Replace("色","");
  
                    car.CarColor = _carcolor[(int)result.nCarColor].ToString();

                    car.CarIDTypeID = ((int)result.nType).ToString();
                    car.CarIDTypeName = _caridtypeid[(int)result.nType];

                    car.CarIDRealVal = result.nConfidence;

                    string carImagePath = string.Format("{0}\\{1:yyyyMMddHHmmssffff}_{2}.jpg", _tempFolder, DateTime.Now, "big");

                    VzClientSDK.VzLPRClient_ImageSaveToJpeg(imgHandler, carImagePath, 100);
                    if (File.Exists(carImagePath))
                    {
                        car.CarBodyPhoto = File.ReadAllBytes(carImagePath);// Image.FromFile(carImagePath);
                    }

                    carImagePath = string.Format("{0}\\{1:yyyyMMddHHmmssffff}_{2}.jpg", _tempFolder, DateTime.Now, "carid");

                    VzClientSDK.VzLPRClient_ImageSaveToJpeg(imgCarIDHandle, carImagePath, 100);
                    if (File.Exists(carImagePath))
                    {
                        car.CarIDPhoto = File.ReadAllBytes(carImagePath);// Image.FromFile(carImagePath);
                    }
                    //string time=result.struBDTime.bdt_year + "-" + result.struBDTime.bdt_mon.ToString().PadLeft(2, '0') +
                    //    "-" + result.struBDTime.bdt_mday.ToString().PadLeft(2, '0') + " " + result.struBDTime.bdt_hour.ToString().PadLeft(2, '0') +
                    //    ":" + result.struBDTime.bdt_min.ToString().PadLeft(2, '0') + ":" +
                    //    result.struBDTime.bdt_sec.ToString().PadLeft(2, '0');


                    car.Time = DateTime.Now;// DateTime.Parse(time);

                    //int size = Marshal.SizeOf(plateInfo);
                    //IntPtr intptr = Marshal.AllocHGlobal(size);
                    //Marshal.StructureToPtr(plateInfo, intptr, true);



                    string ip = _slHandleToIp.ContainsKey(handle) ? _slHandleToIp[handle] : "";
                    car.DeviceIP=ip;
                    ParkHandler.OnCarArriveGate(ip, car);

                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

            return 0;
        }


        #region 透传
        //发送文字内容
        public static int SetText(string ip, int line, DisplayMehod method, string text, int comport=0)
        {
            int serialHandle = GetSerialHanlde(ip, comport);
            if (serialHandle <= 0)
                return -6;
            if (line < 1)
                line = 1;

            byte[] lineid = new byte[] {0x41,0x42,0x43,0x44,0x45 };
            byte[] buffer = Encoding.Default.GetBytes("00" + text);
            buffer[0] = lineid[line - 1];
            buffer[1] = (byte)method;

            
    
            return SerialSend(serialHandle, SerialCommand.TextDisplay, buffer);
        }

        //发送文字内容
        public static int SetText2(string ip, int line, DisplayMehod method, string text, int comport = 0)
        {
            int serialHandle = GetSerialHanlde(ip, comport);
            if (serialHandle <= 0)
                return -6;

            byte[] lineid = new byte[] { 0x41, 0x42, 0x43, 0x44, 0x45 };
            byte[] buffer = Encoding.Default.GetBytes("00" + text);
            buffer[0] = 0x14;
            buffer[1]=lineid[line - 1];
            //buffer[2] = 0x51;// (byte)method;



            return SerialSend(serialHandle, SerialCommand.TextDisplay, buffer);
        }


        //通道类型
        public static int SetGateType(string ip, RTSDK.DeviceDirection dir, int comport = 0)
        {
            int serialHandle = GetSerialHanlde(ip, comport);
            if (serialHandle <= 0)
                return -6;

            byte[] buffer = new byte[2];
            buffer[0] = (byte)SerialSubCommand.GateType;

            if (dir == RTSDK.DeviceDirection.Enter)
                buffer[1] = 1;
            else if (dir == RTSDK.DeviceDirection.Leave)
                buffer[1]=2;
            else if (dir == RTSDK.DeviceDirection.Both)
                buffer[1]=0x0f;
            

            return SerialSend(serialHandle, SerialCommand.ConfigDownload, buffer);
        }

        //是否允许警车自动放行
        public static int SetPoliceCar(string ip, bool isAllow, int comport = 0)
        {
            int serialHandle = GetSerialHanlde(ip, comport);
            if (serialHandle <= 0)
                return -6;


            byte[] buffer = new byte[2];
            buffer[0] = (byte)SerialSubCommand.AgreePoliceCar;
            buffer[1] = isAllow ? (byte)1 : (byte)0;

            return SerialSend(serialHandle, SerialCommand.ConfigDownload, buffer);
        }

        //是否允许临时车入场
        public static int SetTempCar(string ip, bool isAllow, int comport = 0)
        {
            int serialHandle = GetSerialHanlde(ip, comport);
            if (serialHandle <= 0)
                return -6;


            byte[] buffer = new byte[2];
            buffer[0] = (byte)SerialSubCommand.AgreeTempCar;
            buffer[1] = isAllow ? (byte)1 : (byte)0;

            return SerialSend(serialHandle, SerialCommand.ConfigDownload, buffer);
        }

        //车队模式
        public static int SetCarTour(string ip, bool isOpen, int comport = 0)
        {
            int serialHandle = GetSerialHanlde(ip, comport);
            if (serialHandle <= 0)
                return -6;


            byte[] buffer = new byte[1];
            buffer[0] = isOpen ? (byte)SerialSubCommand.CarTourAgree : (byte)SerialSubCommand.CarTourCancel;

            return SerialSend(serialHandle, SerialCommand.CarTour, buffer);
        }

        //设置系统日期
        public static int SetLedTime(string ip, DateTime dt, int comport = 0)
        {
            int serialHandle = GetSerialHanlde(ip, comport);
            if (serialHandle <= 0)
                return -6;

            byte[] buffer = new byte[7];
            buffer[0] = (byte)dt.Second;
            buffer[1] = (byte)dt.Minute;
            buffer[2] = (byte)dt.Hour;
            buffer[3] = (byte)dt.Day;
            buffer[4] = (byte)dt.Month;
            buffer[5] = (byte)((int)dt.DayOfWeek);
            buffer[6] = (byte)((int)dt.Year % 100);

            return SerialSend(serialHandle, SerialCommand.CalcSystemTime, buffer);
        }
        
        //设置音量等级
        public static int SetVolume(string ip, int leave, int comport=0)
        {
            int serialHandle = GetSerialHanlde(ip, comport);
            if (serialHandle <= 0)
                return -6;


            byte[] buffer = new byte[2];
            buffer[0] =(byte)SerialSubCommand.SetVolume;
            buffer[1] =(byte)(leave>9?9:leave);

            return SerialSend(serialHandle, SerialCommand.ConfigDownload, buffer);
        
        }
        
        //设置空内容
        public static int SetFree(string ip, int comport = 0)
        {
            int serialHandle = GetSerialHanlde(ip, comport);
            if (serialHandle <= 0)
                return -6;

            byte[] buffer = new byte[] { };

            return SerialSend(serialHandle, SerialCommand.None, buffer);

        }

        //第四行
        public static int SetText(string ip, string text, int comport = 0)
        {
            int serialHandle = GetSerialHanlde(ip, comport);
            if (serialHandle <= 0)
                return -6;

            byte[] buffer = Encoding.Default.GetBytes("0" + text);
            buffer[0] = 1;

            return SerialSend(serialHandle, SerialCommand.QRDisplay, buffer);

        }

        //显示二维码
        public static int SetQR(string ip, string text, int comport = 0)
        {
            int serialHandle = GetSerialHanlde(ip, comport);
            if (serialHandle <= 0)
                return -6;

            byte[] buffer = Encoding.ASCII.GetBytes("0" + text);
            buffer[0] = 0;

            return SerialSend(serialHandle, SerialCommand.QRDisplay, buffer);

        }

        //播放语音
        public static int PlayVoice(string ip,string text,int comport=0)
        {
            int serialHandle = GetSerialHanlde(ip,comport);
            if (serialHandle <= 0)
                return -6;

            byte[] buffer = StringToVoiceID.GetBytes(text);
            return SerialSend(serialHandle, SerialCommand.PlayVoice, buffer);

        }

        //设置红绿灯
        public static int SetGreenLed(string ip, bool isGreen, int comport = 0)
        {
            int serialHandle = GetSerialHanlde(ip, comport);
            if (serialHandle <= 0)
                return -6;

            byte[] buffer = new byte[1];
            buffer[0] = isGreen ? (byte)0x00 : (byte)0x01;
            return SerialSend(serialHandle, SerialCommand.RegGreenLed, buffer);

        }


        private static int GetSerialHanlde(string ip,int comport)
        {

            if (!_slIpToHandle.ContainsKey(ip))
                return -3;

            int serialHandle = -1;

            if (_slSerialHandle.ContainsKey(ip))
                serialHandle = _slSerialHandle[ip];
            else
            {
                serialHandle = VzClientSDK.VzLPRClient_SerialStart(_slIpToHandle[ip], comport, _serialRecv, IntPtr.Zero);
                if (serialHandle == 0)
                {
                    return -2;
                }

                if (!_slSerialHandle.ContainsKey(ip))
                    _slSerialHandle.Add(ip, serialHandle);
                else
                    _slSerialHandle[ip] = serialHandle;
            }

            return serialHandle;
        }

        private static int SerialSend(int serialHandle, SerialCommand cmd, byte[] data)
        {


            byte[] crcdata = new byte[4+data.Length];
            //buffer[0] = 0xaa;
            //buffer[1] = 0x55;

            crcdata[0] = 0x80;
            crcdata[1] = (byte)cmd;
            crcdata[2] = (byte)(data.Length >>8) ;  //data.length>>8
            crcdata[3] = (byte)data.Length;
            Array.Copy(data,0, crcdata,4, data.Length);

            ushort crc = CRCHelper.CRC16(crcdata, (short)crcdata.Length);

            byte[] buffer = new byte[6 + crcdata.Length];
            buffer[0] = 0xaa;
            buffer[1] = 0x55;
            buffer[2] = 0x7b;
            Array.Copy(crcdata, 0, buffer, 3, crcdata.Length);
            buffer[3 + crcdata.Length] = (byte)(crc>>8);
            buffer[4 + crcdata.Length] = (byte)crc;
            buffer[5 + crcdata.Length] = 0xaf;

            return SerialSend(serialHandle, buffer);
        }

        private static int SerialSend(int serialHandle, byte[] data)
        { 
            GCHandle gcdata = GCHandle.Alloc(data, GCHandleType.Pinned);
            IntPtr dhandle = gcdata.AddrOfPinnedObject();

            return VzClientSDK.VzLPRClient_SerialSend(serialHandle, dhandle, data.Length)==1?0:1;
        }

        #endregion

    }
}
